// GamePanel.java
package game;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class GamePanel extends JPanel {
    private CopyOnWriteArrayList<Fruit> fruits;
    private FruitGenerator fruitGenerator;
    private int score;
    private int fruitGenerationInterval = 2000;
    private Thread fruitGeneratorThread;
    private Thread fruitMovementThread;
    private int timeLeft = 60;
    private Timer timer;
    private boolean isTimePaused = false;
    private List<TrailPoint> trailPoints;
    private static final long TRAIL_DURATION = 500;
    private String specialFruitMessage;
    private long specialFruitMessageStartTime;
    private static final long SPECIAL_FRUIT_MESSAGE_DURATION = 3000;
    private boolean gameActive = true;
    private GameWindow gameWindow;
    private ParticleManager particleManager;
    private ExecutorService collisionExecutor = Executors.newFixedThreadPool(2);

    public GamePanel(GameWindow gameWindow, int initialInterval, int bombChance, int specialFruitChance) {
        this.gameWindow = gameWindow;
        fruits = new CopyOnWriteArrayList<>();
        fruitGenerator = new FruitGenerator(bombChance, specialFruitChance);
        score = 0;
        this.fruitGenerationInterval = initialInterval;
        trailPoints = new ArrayList<>();
        specialFruitMessage = null;
        particleManager = new ParticleManager(this);

        setPreferredSize(new Dimension(800, 600));
        setBackground(Color.WHITE);

        startFruitGeneratorThread();
        startFruitMovementThread();

        addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if (gameActive) {
                    checkCut(e.getX(), e.getY());
                    trailPoints.add(new TrailPoint(e.getX(), e.getY()));
                }
            }
        });

        timer = new Timer(1000, e -> {
            if (!isTimePaused && gameActive) {
                timeLeft--;
                if (timeLeft <= 0) {
                    timer.stop();
                    gameOver();
                }
            }
            repaint();
        });
        timer.start();
    }

    /*
     * 启动水果生成线程
     */
    private void startFruitGeneratorThread() {
        fruitGeneratorThread = new Thread(() -> {
            try {
                while (gameActive) {
                    Thread.sleep(fruitGenerationInterval);
                    if (gameActive) {
                        fruits.addAll(fruitGenerator.generateFruits());
                        if (score % 10 == 0 && score > 0) {
                            fruitGenerationInterval = Math.max(500, fruitGenerationInterval - 100);
                        }
                    }
                }
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        });
        fruitGeneratorThread.start();
    }

    /*
     * 启动水果移动线程
     */
    private void startFruitMovementThread() {
        fruitMovementThread = new Thread(() -> {
            try {
                while (gameActive) {
                    Thread.sleep(16);
                    if (gameActive) {
                        for (Fruit fruit : fruits) {
                            fruit.move();
                        }
                        repaint();
                    }
                }
            } catch (InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        });
        fruitMovementThread.start();
    }

    private void checkCut(int mouseX, int mouseY) {
        if (!gameActive) return;

        collisionExecutor.submit(() -> {
            Iterator<Fruit> iterator = fruits.iterator();
            while (iterator.hasNext()) {
                Fruit fruit = iterator.next();
                if (fruit.isCut(mouseX, mouseY)) {
                    SwingUtilities.invokeLater(() -> {
                        if (gameActive) {
                            if (fruit.isBomb()) {
                                gameOver();
                            } else {
                                if (fruit.isSpecial()) {
                                    handleSpecialFruit(fruit.getSpecialEffect());
                                } else {
                                    score++;
                                }
                                particleManager.createParticles(fruit.getX(), fruit.getY(), fruit.getSymbol());
                                fruits.remove(fruit);
                            }
                        }
                    });
                }
            }
        });
    }

    private void handleSpecialFruit(int specialEffect) {
        if (!gameActive) return;

        switch (specialEffect) {
            case 1:
                score += 2;
                showSpecialMessage("双倍得分！");
                break;
            case 2:
                isTimePaused = true;
                showSpecialMessage("时间暂停 5 秒！");
                Timer pauseTimer = new Timer(5000, e -> {
                    if (gameActive) {
                        isTimePaused = false;
                    }
                });
                pauseTimer.setRepeats(false);
                pauseTimer.start();
                break;
            case 3:
                timeLeft = Math.max(0, timeLeft - 3);
                if (timeLeft <= 0) {
                    timer.stop();
                    gameOver();
                }
                showSpecialMessage("时间减去 3 秒！");
                break;
        }
    }

    private void showSpecialMessage(String message) {
        specialFruitMessage = message;
        specialFruitMessageStartTime = System.currentTimeMillis();
    }

    private void gameOver() {
        if (!gameActive) return;

        gameActive = false;

        if (timer != null) {
            timer.stop();
        }

        if (fruitGeneratorThread != null && fruitGeneratorThread.isAlive()) {
            fruitGeneratorThread.interrupt();
        }

        if (fruitMovementThread != null && fruitMovementThread.isAlive()) {
            fruitMovementThread.interrupt();
        }

        if (particleManager != null) {
            particleManager.stop();
        }

        if (collisionExecutor != null) {
            collisionExecutor.shutdownNow();
        }

        SwingUtilities.invokeLater(() -> {
            int choice = JOptionPane.showOptionDialog(
                    this,
                    "游戏结束！你的得分是: " + score + "\n是否再玩一次?",
                    "游戏结束",
                    JOptionPane.YES_NO_OPTION,
                    JOptionPane.QUESTION_MESSAGE,
                    null,
                    new Object[]{"再玩一次", "退出"},
                    "再玩一次"
            );

            if (choice == JOptionPane.YES_OPTION) {
                gameWindow.restartGame();
            } else {
                System.exit(0);
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setFont(new Font("", Font.PLAIN, 20));
        g.drawString("时间: " + timeLeft + " 秒", 10, 30);
        g.drawString("得分: " + score, 10, 60);

        if (specialFruitMessage != null) {
            long currentTime = System.currentTimeMillis();
            if (currentTime - specialFruitMessageStartTime < SPECIAL_FRUIT_MESSAGE_DURATION) {
                g.setColor(Color.RED);
                g.drawString(specialFruitMessage, getWidth() / 2 - 50, getHeight() / 2);
            } else {
                specialFruitMessage = null;
            }
        }

        long currentTime = System.currentTimeMillis();
        trailPoints.removeIf(point -> currentTime - point.creationTime > TRAIL_DURATION);

        for (TrailPoint point : trailPoints) {
            float alpha = 1.0f - (float) (currentTime - point.creationTime) / TRAIL_DURATION;
            int alphaValue = (int) (alpha * 255);
            g.setColor(new Color(255, 0, 0, alphaValue));
            g.fillRect(point.x, point.y, 3, 3);
        }

        g.setColor(Color.BLACK);

        if (gameActive) {
            for (Fruit fruit : fruits) {
                fruit.draw(g);
            }
            particleManager.drawParticles(g);
        } else {
            g.setFont(new Font("", Font.BOLD, 40));
            g.setColor(Color.RED);
            g.drawString("游戏结束!", getWidth() / 2 - 100, getHeight() / 2 - 20);
            g.setFont(new Font("", Font.PLAIN, 30));
            g.drawString("最终得分: " + score, getWidth() / 2 - 100, getHeight() / 2 + 30);
        }
    }
}